using System;
using System.Collections.Generic;
using Com.ContentRendering.Api.RenderEngine.Resolver;

namespace Com.ContentRendering.Api.RenderEngine.Reader
{
    /// <summary/>
    internal class ResolverReader
    {
        private Stack<AbstractResolver> _stack;
        private string _value;

        /// <summary/>
        internal ResolverReader(AbstractResolver resolver)
        {
            this._stack = new Stack<AbstractResolver>();

            // append the resolver to the list
            this._stack.Push(resolver);
        }

        /// <summary/>
        internal bool MoveNext()
        {
            // when the stack is empty ... indicate it
            if (this._stack.Count == 0)
            {
                return false;
            }

            // pull the first thing off the list
            AbstractResolver resolver = this._stack.Pop();

            // is the resolver a parent
            if (resolver.IsParent())
            {
                Stack<AbstractResolver> reversedStack = new Stack<AbstractResolver>();

                // add all of its children to the list
                using (IEnumerator<AbstractResolver> enumerator = resolver.Children)
                {
                    // move all of the values onto a tempoary stack so the values are reversed
                    while (enumerator.MoveNext())
                    {
                        reversedStack.Push(enumerator.Current);
                    }
                }

                // move the items onto the stack such that there order is correct
                foreach (AbstractResolver childResolver in reversedStack)
                {
                    this._stack.Push(childResolver);
                }

                // set an empty value
                this._value = string.Empty;
            }
            else
            {
                // record the value
                this._value = resolver.Value;
            }
            
            return true;
        }

        /// <summary/>
        internal string Value
        {
            get { return this._value; }
        }
    }
}
